﻿using NetCore.Ado;
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Common;
using System.Linq;
namespace NetCore
{
    public class DataParameter : DbParameter
    {
        public bool IsRefCursor { get; set; }

        public string StrDbType { get; set; }
        public DataParameter(string name, object value)
        {
            this.Value = value;
            this.ParameterName = name;
            if (value != null)
            {
                SettingType(value.GetType());
            }
            else
            {
                this.Value = DBNull.Value;
            }
        }
        public DataParameter(string name, object value, Type type)
        {
            this.Value = value;
            this.ParameterName = name;
            if (value != null)
            {
                SettingType(value.GetType());
            }
            else
            {
                this.Value = DBNull.Value;
            }
        }
        public DataParameter(string name, object value, string dbType)
        {
            this.Value = value;
            this.ParameterName = name;
            IsRefCursor=true;
            StrDbType = dbType;
            if (value != null)
            {
               // SettingType(value.GetType());
            }
            else
            {
                this.Value = DBNull.Value;
            }
            //SettingType(type);
        }
        public DataParameter(string name, object value, Type type, ParameterDirection direction)
        {
            this.Value = value;
            this.ParameterName = name;
            this.Direction = direction;
            if (value != null)
            {
                 SettingType(value.GetType());
            }
            else
            {
                this.Value = DBNull.Value;
            }
        }
        public DataParameter(string name, object value, Type type, ParameterDirection direction, int size)
        {
            this.Value = value;
            this.ParameterName = name;
            this.Direction = direction;
            this.Size = size;
            if (value != null)
            {
                SettingType(value.GetType());
            }
            else
            {
                this.Value = DBNull.Value;
            }
        }

        private void SettingType(Type type)
        {
            if (type == typeof(byte[]))
            {
                this.DbType = System.Data.DbType.Binary;
            }
            else if (type == typeof(Guid))
            {
                this.DbType = System.Data.DbType.Guid;
            }
            else if (type == typeof(int))
            {
                this.DbType = System.Data.DbType.Int32;
            }
            else if (type == typeof(short))
            {
                this.DbType = System.Data.DbType.Int16;
            }
            else if (type == typeof(long))
            {
                this.DbType = System.Data.DbType.Int64;
            }
            else if (type == typeof(DateTime))
            {
                this.DbType = System.Data.DbType.DateTime;
            }
            else if (type == typeof(double))
            {
                this.DbType = System.Data.DbType.Double;
            }
            else if (type == typeof(Decimal))
            {
                this.DbType = System.Data.DbType.Decimal;
            }
            else if (type == typeof(Byte))
            {
                this.DbType = System.Data.DbType.Byte;
            }
            else if (type == typeof(float))
            {
                this.DbType = System.Data.DbType.Single;
            }
            else if (type == typeof(bool))
            {
                this.DbType = System.Data.DbType.Boolean;
            }
            else if (type == typeof(string))
            {
                this.DbType = System.Data.DbType.String;
            }

        }

        public DataParameter(string name, object value, bool isOutput)
        {
            this.Value = value;
            this.ParameterName = name;
            if (isOutput)
            {
                this.Direction = ParameterDirection.Output;
            }
        }
        public override System.Data.DbType DbType
        {
            get;
            set;
        }

        public override ParameterDirection Direction
        {
            get;
            set;
        }

        public override bool IsNullable
        {
            get;
            set;
        }

        public override string ParameterName
        {
            get;
            set;
        }

        public int _Size;

        public override int Size
        {
            get
            {
                if (_Size == 0 && Value != null)
                {
                    var isByteArray = Value.GetType() == typeof(byte[]);
                    if (isByteArray)
                        _Size = -1;
                    else
                    {
                        var length = Value.ToString().Length;
                        _Size = length < 4000 ? 4000 : -1;

                    }
                }
                if (_Size == 0)
                    _Size = 4000;
                return _Size;
            }
            set
            {
                _Size = value;
            }
        }

        public override string SourceColumn
        {
            get;
            set;
        }

        public override bool SourceColumnNullMapping
        {
            get;
            set;
        }
        public string UdtTypeName
        {
            get;
            set;
        }

        public override object Value
        {
            get;
            set;
        }

        public Dictionary<string, object> TempDate
        {
            get;
            set;
        }

        /// <summary>
        /// 如果类库是.NET 4.5请删除该属性
        /// If the SqlSugar library is.NET 4.5, delete the property
        /// </summary>
        public override DataRowVersion SourceVersion
        {
            get;
            set;
        }

        public override void ResetDbType()
        {
            this.DbType = System.Data.DbType.String;
        }
    }

    public class DataParameterCollection: List<DbParameter>
    {
        protected IDbRepository DbRepository = null;
      
        public DataParameterCollection(IDbRepository dbRepository)
        {
            this.DbRepository = dbRepository;
           // _collection = new List<DataParameter>();
        }
        public void Add(DataParameter parameter)
        {
            this.Add(DbRepository.MakeParam(parameter.ParameterName, parameter.DbType, parameter.Size, parameter.Direction, (parameter.Value == null) ? DBNull.Value : parameter.Value));
        }
        public void Add(string parameterName,object value)
        {
            this.Add(DbRepository.GetParameter( parameterName,value));
        }
        public void Add(DataParameter parameter, ref string paramName)
        {
            string paramName1 = paramName = paramName.Replace(".", "");
            parameter.ParameterName = paramName1;
            var result = this.Where(x => x.ParameterName.Equals(paramName1)).FirstOrDefault();
            int index = 0;
            if (result != null)
            {
                paramName = parameter.ParameterName + "_" + index.ToString();
                this.Add(parameter, ref paramName, index);
                parameter.ParameterName = paramName;
            }
            this.Add(parameter);

        }
        private void Add(DataParameter parameter, ref string paramName,int index)
        {
            string paramName1 = paramName;
            var result = this.Where(x => x.ParameterName.Equals(paramName1)).FirstOrDefault();
            if (result != null)
            {
                paramName = parameter.ParameterName + "_" + index.ToString();
                index++;
                this.Add(parameter, ref paramName, index);
            }
        }

        
        /// <summary>
        /// 获取参数格式
        /// </summary>
        /// <param name="propertyName"></param>
        /// <returns></returns>
        public string GetParameter(string propertyName)
        {
            return DbRepository.GetParameter(propertyName);
        }


    }
}
